package com.rabincorp.tactile.feed;

import com.rabincorp.tactile.common.TactileCommon;
import com.rabincorp.tactile.entity.MediaContentItem;
import com.rabincorp.tactile.entity.MediaThumbnail;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import com.rabincorp.tactile.entity.YouTubeVideoItem;
import com.sun.syndication.feed.module.mediarss.MediaEntryModule;
import com.sun.syndication.feed.module.mediarss.MediaModule;
import com.sun.syndication.feed.module.mediarss.types.MediaContent;
import com.sun.syndication.feed.module.mediarss.types.MediaGroup;
import com.sun.syndication.feed.module.mediarss.types.Metadata;
import com.sun.syndication.feed.module.mediarss.types.Thumbnail;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.fetcher.FeedFetcher;
import com.sun.syndication.fetcher.FetcherException;
import com.sun.syndication.fetcher.impl.FeedFetcherCache;
import com.sun.syndication.fetcher.impl.HashMapFeedInfoCache;
import com.sun.syndication.fetcher.impl.HttpURLFeedFetcher;
import com.sun.syndication.io.FeedException;
import org.jdom.Element;


public class YouTubeFeed {

    private static YouTubeFeed instance = null;
    

    public static YouTubeFeed getInstance() {
        if (instance == null) {
            instance = new YouTubeFeed();
        }

        return instance;
    }

    @SuppressWarnings("unchecked")
    public List<YouTubeVideoItem> parse(String feedURL) {

        List<YouTubeVideoItem> videoItems = new ArrayList<YouTubeVideoItem>();

        try {
            URL url = new URL(feedURL);

            FeedFetcherCache feedInfoCache = HashMapFeedInfoCache.getInstance();
            FeedFetcher fetcher = new HttpURLFeedFetcher(feedInfoCache);

            SyndFeed feed = fetcher.retrieveFeed(url);
            List<SyndEntry> entries = (List<SyndEntry>) feed.getEntries();
            for (SyndEntry entry : entries) {

                YouTubeVideoItem video = new YouTubeVideoItem();

                video.setGuid(entry.getUri());
                video.setTitle(entry.getTitle());
                video.setLink(entry.getLink());
                video.setPubDate(entry.getPublishedDate());


                MediaModule mediaModule = (MediaModule) entry.getModule(MediaModule.URI);
                if (mediaModule != null && mediaModule instanceof MediaEntryModule) {

                    MediaEntryModule mediaEntry = (MediaEntryModule) mediaModule;
                    for (MediaGroup mg : mediaEntry.getMediaGroups()) {
                        for (MediaContent mc : mg.getContents()) {

                            MediaContentItem contentItem = new MediaContentItem();

                            contentItem.setAudioChannels(mc.getAudioChannels());
                            contentItem.setBitRate(mc.getBitrate() != null ? new Float(mc.getBitrate().floatValue()) : null);
                            contentItem.setDuration(mc.getDuration() != null ? new Float(mc.getDuration().floatValue()) : null);
                            contentItem.setFileSize(mc.getFileSize() != null ? new Long(mc.getFileSize().longValue()) : null);
                            contentItem.setFrameRate(mc.getFramerate() != null ? new Float(mc.getFramerate().floatValue()) : null);
                            contentItem.setHeight(mc.getHeight() != null ? new Long(mc.getHeight().longValue()) : null);
                            contentItem.setLanguage(mc.getLanguage());
                            contentItem.setReference(mc.getReference().toString());
                            contentItem.setSamplingRate(mc.getSamplingrate() != null ? new Float(mc.getSamplingrate().floatValue()) : null);
                            contentItem.setType(mc.getType());
                            contentItem.setWidth(mc.getWidth() != null ? new Long(mc.getWidth().longValue()) : null);

                            video.getContents().add(contentItem);
                        }

                        Metadata metadata = mg.getMetadata();
                        for (Thumbnail thumbnail : metadata.getThumbnail()) {
                            MediaThumbnail videoThumbnail = new MediaThumbnail();
                            videoThumbnail.setHeight(thumbnail.getHeight());
                            videoThumbnail.setWidth(thumbnail.getWidth());
                            videoThumbnail.setUrl(thumbnail.getUrl().toString());
                            video.getThumbnails().add(videoThumbnail);
                        }
                        video.getKeywords().addAll(Arrays.asList(metadata.getKeywords()));
                        
                        String description = metadata.getDescription();
                        description = description.replace("www.hahaha.com", "");
                        video.setDescription(description);

                    }

                }
                
                List<Object> foreignMarkupList = (List<Object>) entry.getForeignMarkup();
                for (Object object: foreignMarkupList) {
                    Element element = (Element) object;
                    if (element.getName().equalsIgnoreCase("updated") || element.getName().equalsIgnoreCase("comments")||
                            element.getName().equalsIgnoreCase("rating")) {
                        video.getElements().put(element.getName(), element);
                    }
                }

                videoItems.add(video);
            }

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FeedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (FetcherException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return videoItems;
    }

    public static void main(String[] args) {

        YouTubeFeed youtubeGrabber = YouTubeFeed.getInstance();


        int counter = 0;

        List<YouTubeVideoItem> videoList = youtubeGrabber.parse(TactileCommon.GAGS_CHANNEL);
        for (YouTubeVideoItem videoItem : videoList) {
            System.out.println(++counter + ". Title: " + videoItem.getTitle() + " - " + videoItem.getLink());
        }

    }
}
